using Entitas;
using Entitas.Unity.Serialization.Blueprints;
using UnityEngine;

public class GameController : MonoBehaviour {

    public Blueprints blueprints;

    [SerializeField]
    private Transform canvas;

    Systems _systems;

    void Awake() {
        Application.targetFrameRate = 60;
    }

    void Start() {

        GameRandom.core = new Rand(0);
        GameRandom.view = new Rand(0);

        var pools = Contexts.sharedInstance;
        pools.SetAllContexts();
        pools.AddEntityIndices();

        pools.blueprints.SetBlueprints(blueprints);

        _systems = createSystems(pools);

        // Suggested systems lifecycle:
        // systems.Initialize() on Start
        // systems.Execute() on Update
        // systems.Cleanup() on Update after systems.Execute()
        // systems.TearDown() on OnDestroy

        _systems.Initialize();

        pools.core.CreateEntity()
            .AddParent(canvas)
            .AddAsset(Res.HUD);
    }

    void Update() {
        _systems.Execute();
        _systems.Cleanup();
    }

    void OnDestroy() {
        _systems.TearDown();
    }

    Systems createSystems(Contexts contexts) {
        return new Feature("Systems")

            // Initialize
            .Add(new IncrementTickSystem(contexts))
            .Add(new CreatePlayerSystem(contexts))
            .Add(new CreateEnemySystem(contexts))

            .Add(new AddViewSystem(contexts))
            .Add(new AddViewFromObjectPoolSystem(contexts))

            // Input
            .Add(new InputSystem(contexts))
            .Add(new ProcessMoveInputSystem(contexts))
            .Add(new ProcessShootInputSystem(contexts))
            .Add(new ProcessCollisionSystem(contexts))
            .Add(new SlowMotionSystem(contexts))

            // Update
            .Add(new BulletCoolDownSystem(contexts))
            .Add(new StartEnemyWaveSystem(contexts))
            .Add(new NotifyStatisticsChangeSystem(contexts))
            .Add(new VelocitySystem(contexts))
            .Add(new RenderPositionSystem(contexts.core))
            .Add(new RenderPositionSystem(contexts.bullets))
            .Add(new CheckHealthSystem(contexts))
            .Add(new BulletOutOfScreenSystem(contexts))

            // Game State

            // Animate Destroy
            .Add(new AnimateOutOfScreenViewSystem(contexts))
            .Add(new DestroyViewSystem(contexts))

            // Destroy
            .Add(new DestroyEntitySystem(contexts));
    }
}
